/*
 * common.hpp
 *
 *  Created on: 2009-9-26
 *      Author: ws
 */

#ifndef COMMON_HPP_
#define COMMON_HPP_

#include<sstream>
#include<string>

enum Core {
	NO_CORE = -1,
	CORE_X,
	CORE_Y,
	CORE_Z,
	CORE_T,
	MU_U,
	MU_V,
	MU_W,
	SUM_CORE
};


namespace TargetInfo{
enum PhysicalRegister{
XR0 = 1,
XR1,
XR2,
XR3,
XR4,
XR5,
XR6,
XR7,
XR8,
XR9,
XR10,
XR11,
XR12,
XR13,
XR14,
XR15,
XR16,
XR17,
XR18,
XR19,
XR20,
XR21,
XR22,
XR23,
XR24,
XR25,
XR26,
XR27,
XR28,
XR29,
XR30,
XR31,
XR32,
XR33,
XR34,
XR35,
XR36,
XR37,
XR38,
XR39,
XR40,
XR41,
XR42,
XR43,
XR44,
XR45,
XR46,
XR47,
XR48,
XR49,
XR50,
XR51,
XR52,
XR53,
XR54,
XR55,
XR56,
XR57,
XR58,
XR59,
XR60,
XR61,
XR62,
XR63,
YR0,
YR1,
YR2,
YR3,
YR4,
YR5,
YR6,
YR7,
YR8,
YR9,
YR10,
YR11,
YR12,
YR13,
YR14,
YR15,
YR16,
YR17,
YR18,
YR19,
YR20,
YR21,
YR22,
YR23,
YR24,
YR25,
YR26,
YR27,
YR28,
YR29,
YR30,
YR31,
YR32,
YR33,
YR34,
YR35,
YR36,
YR37,
YR38,
YR39,
YR40,
YR41,
YR42,
YR43,
YR44,
YR45,
YR46,
YR47,
YR48,
YR49,
YR50,
YR51,
YR52,
YR53,
YR54,
YR55,
YR56,
YR57,
YR58,
YR59,
YR60,
YR61,
YR62,
YR63,
ZR0,
ZR1,
ZR2,
ZR3,
ZR4,
ZR5,
ZR6,
ZR7,
ZR8,
ZR9,
ZR10,
ZR11,
ZR12,
ZR13,
ZR14,
ZR15,
ZR16,
ZR17,
ZR18,
ZR19,
ZR20,
ZR21,
ZR22,
ZR23,
ZR24,
ZR25,
ZR26,
ZR27,
ZR28,
ZR29,
ZR30,
ZR31,
ZR32,
ZR33,
ZR34,
ZR35,
ZR36,
ZR37,
ZR38,
ZR39,
ZR40,
ZR41,
ZR42,
ZR43,
ZR44,
ZR45,
ZR46,
ZR47,
ZR48,
ZR49,
ZR50,
ZR51,
ZR52,
ZR53,
ZR54,
ZR55,
ZR56,
ZR57,
ZR58,
ZR59,
ZR60,
ZR61,
ZR62,
ZR63,
TR0,
TR1,
TR2,
TR3,
TR4,
TR5,
TR6,
TR7,
TR8,
TR9,
TR10,
TR11,
TR12,
TR13,
TR14,
TR15,
TR16,
TR17,
TR18,
TR19,
TR20,
TR21,
TR22,
TR23,
TR24,
TR25,
TR26,
TR27,
TR28,
TR29,
TR30,
TR31,
TR32,
TR33,
TR34,
TR35,
TR36,
TR37,
TR38,
TR39,
TR40,
TR41,
TR42,
TR43,
TR44,
TR45,
TR46,
TR47,
TR48,
TR49,
TR50,
TR51,
TR52,
TR53,
TR54,
TR55,
TR56,
TR57,
TR58,
TR59,
TR60,
TR61,
TR62,
TR63,
UR0,
UR1,
UR2,
UR3,
UR4,
UR5,
UR6,
UR7,
UR8,
UR9,
UR10,
UR11,
UR12,
UR13,
UR14,
UR15,
VR0,
VR1,
VR2,
VR3,
VR4,
VR5,
VR6,
VR7,
VR8,
VR9,
VR10,
VR11,
VR12,
VR13,
VR14,
VR15,
WR0,
WR1,
WR2,
WR3,
WR4,
WR5,
WR6,
WR7,
WR8,
WR9,
WR10,
WR11,
WR12,
WR13,
WR14,
WR15,
};

enum Core T_get_core(enum PhysicalRegister reg);

}//end namespace


enum Flow_Type{
	REBACK_FT,
	FALL_FT,
	OUT_FT,
	JUMP_FT
};

enum BLKType{
	ENTRY_BT,
	EXIT_BT,
	UNROLL_LOOP_BT,
	PREHEADER_BT,
	REMAINDER_BT,
	NORMAL_BT
};

/*
 * a node is spill store node or spill load node
 */

enum NType {
		LOAD = 0x0001,
		STORE = 0x002,
		NORMAL_OPER = 0x004,

		ADDR_OPER = 0x0008,
		ADDR_DATA = 0x0010,
		DATA_ADDR = 0x0020,

		DATA_SR = 0x00040,
		JSR_SR = 0x0080,
		JSR = 0x00100,

		RTS = 0x00200,
		BR_OPER= 0x0400,

		//special node
		START_NODE = 0x0800,
		END_NODE = 0x1000,
		/*
		 * >>>>>>>>>>>>>> following for the spill <<<<<<<<<<<<<<<<<<<
		 */
		SPILL = 0x2000,
		SIMD = 0x4000

};
#define SIMD_LOAD (LOAD|SIMD)

#define SIMD_STORE (STORE |SIMD)

#define SIMD_MATH  (SIMD |NORMAL_OPER)

#define SPILL_LOAD (SPILL |LOAD)
#define SPILL_STORE (SPILL |STORE)

#define SPILL_SIMD_LOAD (SPILL |LOAD | SIMD)
#define SPILL_SIMD_STORE (SPILL |STORE |SIMD)

#define ALL_NODE (0xFFFF)

// represent the operand
enum LOC_Type{
	FACK = -1,
	SRC,
	DEST,
	IMPLICT_SRC,
	IMPLICT_DEST,
	SRC_MEM,
	DEST_MEM,
	CTR,
	OPD_SUM
};

#define OPD_SRC (SRC|IMPLICT_SRC)

std::string Get_OPDType_Name(enum LOC_Type opdtype);
//represent the dep type
enum  DType {
	RAW = 0x000001,
	WAW = 0x000002,
	WAR = 0x000004,
	MEM_RAW = 0x000008,
	MEM_WAW = 0x000010,
	MEM_WAR = 0x000020,
	CTR_CTR = 0x000040,
	CTR_MEM = 0x000080,
	MEM_CTR = 0x000100,
	FACK_DEP = 0x000200
};

#define IS_MEM_DEP(flag) 	((MEM_RAW|MEM_WAW|MEM_WAR)&(flag))


/*
 * define the filter_iter for dep iterator and node iterator
 */
struct _flag_mask{
	bool operator()(unsigned int mask, unsigned int flag)
	{
		if(mask & flag )
			return true;
		else
			return false;
	}
};



//help class for dep class;
struct location{
	enum LOC_Type  operand_type;
	int index;
	location(enum LOC_Type operand_type, int index): operand_type(operand_type), index(index)
	{
		;
	}
	inline std::string str()const
	{
		std::ostringstream os ;
		os<<Get_OPDType_Name(operand_type)<<", "<<index;
		return os.str();
	}
	inline bool operator == (const location&  loc)const
	{
		if(( operand_type == loc.operand_type)&& index == loc.index)
			return true;
		else
			return false;
	}

	inline bool operator != (const location & loc)const
	{
		return ! (loc == (*this));
	}
};




#endif /* COMMON_HPP_ */
